package org.heydr.datacenter.db;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.apache.http.Header;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.heydr.common.http.Proxy;
import org.heydr.entity.HttpSnatchParam;
import org.heydr.entity.Site;
import org.heydr.entity.Url;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.stereotype.Repository;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

@Repository
public class DataAccess extends JdbcTemplate {
	
	public List<Site> availableSiteInfos(){
		List<Site> list = null;
		try {
			list = query("select * from siteInfo where crawlStatus=1", new SiteMapper());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
	
	public List<Url> fetchTasks(int mod,int totalCore,int size) {
		return query("select * from urlInfo where status!=1 and type=1 and id%?=? limit ?",ParameterizedBeanPropertyRowMapper.newInstance(Url.class),totalCore,mod,size);
	}
	
	public void finishedTasks(List<Url> urls){
		if(null != urls && urls.size()>0){
			List<Object[]> parameters = new ArrayList<Object[]>();
			for(Url u:urls){
				parameters.add(new Object[] {u.getUrlMd5()});  
			}
			batchUpdate("update urlInfo set status=1 where urlMd5=?", parameters);
		}
	}

	public void storeUrls(List<Url> urls){
		if(null != urls && urls.size()>0){
			List<Object[]> parameters = new ArrayList<Object[]>();
			for(Url u:urls){
				parameters.add(new Object[]{u.getUrl(),u.getUrlMd5(),u.getParentUrl(),u.getSiteName(),u.getEntryUrl(),u.getSite(),u.getStatus(),u.getType(),u.getFailTimes(),u.getUpdateTime()});  
			}
			batchUpdate("insert ignore into urlInfo(url,urlMd5,parentUrl,siteName,entryUrl,site,status,type,failTimes,createTime,updateTime) values(?,?,?,?,?,?,?,?,?,now(),?)",parameters);
		}
	}
	
	public List<Url> fetchUrlMD5(){
		return query("select site,urlMd5 from urlInfo", ParameterizedBeanPropertyRowMapper.newInstance(Url.class));
	}
	
	public int fetchCurrentId(String urlMd5){
		return queryForInt("select id from urlinfo where urlMd5=? limit 1",urlMd5);
	}
	
	@Override
	@Autowired
	public void setDataSource(DataSource dataSource) {
		super.setDataSource(dataSource);
	}
	
	class SiteMapper implements RowMapper<Site>{

		@Override
		public Site mapRow(ResultSet rs, int arg1) throws SQLException {
			Site site = new Site();
			site.setId(rs.getInt("id"));
			site.setEntryUrl(rs.getString("entryUrl"));
			site.setSite(rs.getString("site"));
			site.setName(rs.getString("name"));
			site.setSleepTime(rs.getInt("sleepTime"));
			
			HttpSnatchParam httpSnatchParam = new HttpSnatchParam();
			
			String requestHeader = rs.getString("requestHeader");
			if(!requestHeader.isEmpty()){
				Gson gson = new Gson();
				List<Header> headers = gson.fromJson(requestHeader, new TypeToken<List<BasicHeader>>() {
				}.getType());
				httpSnatchParam.addRequestHeaders(headers);
			}
			
			String proxy = rs.getString("proxy");
			if(!proxy.isEmpty()){
				Gson gson = new Gson();
				Proxy proxy2 = gson.fromJson(proxy, Proxy.class);
				httpSnatchParam.setProxy(proxy2);
			}
			
			String postParam = rs.getString("postParam");
			if(!postParam.isEmpty()){
				Gson gson = new Gson();
				List<NameValuePair> nvp = gson.fromJson(postParam, new TypeToken<List<BasicNameValuePair>>(){}.getType());
				httpSnatchParam.setPostParams(nvp);
			}
			
			
			site.setHttpSnatchParam(httpSnatchParam);
			
			return site;
		}
	}
}
